# Makefile for STM32G431 PCAN-FD Project

# Toolchain setup
PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
OD = $(PREFIX)objdump
NM = $(PREFIX)nm
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S

# MCU configuration
MCU = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard

# Compiler flags
CFLAGS = $(MCU) -DUSE_HAL_DRIVER -DSTM32G431xx -DPCAN_PRO_FD -O0 -g3
CFLAGS += -Wall -fdata-sections -ffunction-sections
CFLAGS += -fno-omit-frame-pointer -gdwarf-2

# Linker flags
LDFLAGS = $(MCU) -specs=nano.specs -TSTM32G431C8TX_FLASH.ld
LDFLAGS += -Wl,--gc-sections -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref

# Include directories
C_INCLUDES =  \
-ICore/Inc \
-ICore/User \
-IDrivers/STM32G4xx_HAL_Driver/Inc \
-IDrivers/CMSIS/Device/ST/STM32G4xx/Include \
-IDrivers/CMSIS/Include \
-IUSB_Device/App \
-IUSB_Device/Target \
-IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc

# Source files
C_SOURCES =  \
Core/Src/main.c \
Core/Src/stm32g4xx_hal_msp.c \
Core/Src/stm32g4xx_it.c \
Core/Src/system_stm32g4xx.c \
Core/Src/syscalls.c \
Core/Src/sysmem.c \
Core/User/can.c \
Core/User/log.c \
Core/User/pcanpro_fd_protocol.c \
Core/User/pcanpro_led.c \
Core/User/pcanpro_timestamp.c \
Core/User/pcanpro_usbd.c \
Core/User/system.c \
Core/User/util_ringbuffer.c \
Core/User/util_tfp.c \
USB_Device/App/usb_device.c \
USB_Device/App/usbd_desc.c \
USB_Device/Target/usbd_conf.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_fdcan.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pcd.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pcd_ex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_uart_ex.c \
Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_ll_usb.c \
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c

# ASM sources
ASM_SOURCES = Core/Startup/startup_stm32g431c8tx.s

# Build directory
BUILD_DIR = build
TARGET = pcanfd

# Object files
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))

# ASM objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

# Default target
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/$(TARGET).lst $(BUILD_DIR)/$(TARGET).symbols

# Create build directory
$(BUILD_DIR):
	@mkdir -p $@

# Compile C files
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
	$(CC) -c $(CFLAGS) $(C_INCLUDES) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

# Compile ASM files
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@

# Link
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

# Generate hex file
$(BUILD_DIR)/$(TARGET).hex: $(BUILD_DIR)/$(TARGET).elf
	$(HEX) $< $@

# Generate binary file
$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf
	$(BIN) $< $@

# Generate disassembly with source code (for debugging)
$(BUILD_DIR)/$(TARGET).lst: $(BUILD_DIR)/$(TARGET).elf
	$(OD) -S $< > $@

# Generate symbol table (for debugging)
$(BUILD_DIR)/$(TARGET).symbols: $(BUILD_DIR)/$(TARGET).elf
	$(NM) $< > $@

# Clean
clean:
	-rm -fR $(BUILD_DIR)

# Flash using OpenOCD (adjust for your programmer)
flash: $(BUILD_DIR)/$(TARGET).elf
	openocd -f interface/stlink.cfg -f target/stm32g4x.cfg -c "program $< verify reset exit"

# Debug info
debug-info:
	@echo "Target: $(TARGET)"
	@echo "MCU: $(MCU)"
	@echo "Source files: $(words $(C_SOURCES)) C, $(words $(ASM_SOURCES)) ASM"
	@echo "Build directory: $(BUILD_DIR)"

.PHONY: all clean flash debug-info